package com.collect.common.utils.http;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Map;

/**
 * @ Author :hky
 * @ Date  : Created in 17:27 2022-05-17
 * @ Version discord
 * @ Decribtion : $
 */
public class HttpClientUtils {

    private static final Integer CONNECTTIMEOUT = 35000;
    private static final Integer SOCKETTIMEOUT = 60000;

    public static void main(String[] args) {
        String s = doGet("https://www.binance.com/api/v3/ticker/price", null, null, true);
        System.out.println(s);
    }

    /**
     * 带参数get请求
     *
     * @param url   请求接口的url
     * @param param 接口需要传递的参数
     * @param token token 验证
     * @return
     */
    public static String doGet(String url, Map<String, String> param, String token,boolean isHttps) {
        // 创建一个默认可关闭的Httpclient 对象
        CloseableHttpClient httpClient;
        if(isHttps){
            httpClient=SSLClient.getHttpClient(true);
        }else{
            httpClient = HttpClients.createDefault();

        }
        // 设置返回值
        String resultMsg = "";
        // 定义HttpResponse 对象
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            // 创建URI,可以设置host，设置参数等
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            //设置head信息
            setHead(httpGet, token);
            // 执行请求
            response = httpClient.execute(httpGet);
            // 判断返回状态为200则给返回值赋值
            if (response.getStatusLine().getStatusCode() == 200) {
                resultMsg = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultMsg;
    }



    /**
     * 2.发起POST请求
     *
     * @param url  请求url
     * @param data 请求参数（json）
     * @return
     * @throws Exception JSONObject
     * @desc ：
     */
    public static JSONObject doPost(String url, Object data, String token) throws Exception {
        //1.生成一个请求
        HttpPost httpPost = new HttpPost(url);
        //2设置head信息
        setHead(httpPost, token);
        //2.2 设置数据传输格式-json
        httpPost.addHeader("Content-Type", "application/json");
        //2.3 设置请求实体，封装了请求参数
        StringEntity requestEntity = new StringEntity(JSON.toJSONString(data), "utf-8");
        httpPost.setEntity(requestEntity);
        //3.发起请求，获取响应信息
        //3.1 创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            //3.3 发起请求，获取响应
            response = httpClient.execute(httpPost, new BasicHttpContext());
            if (response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            //获取响应内容
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");
                //解析响应内容
                JSONObject result = JSON.parseObject(resultStr);
                if (result.getInteger("errcode") == null) {
                    return result;
                } else if (0 == result.getInteger("errcode")) {
                    return result;
                } else {
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:" + errCode + ", error message:" + errMsg);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();              //释放资源

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    /**
     * @param url  请求url
     * @param file 上传的文件
     * @return
     * @throws Exception JSONObject
     * @desc ： 3.上传文件
     */
    public static JSONObject uploadFile(String url, File file, String token) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        //1设置head信息
        setHead(httpPost, token);
        //2 设置请求实体，封装了请求参数
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpEntity requestEntity = MultipartEntityBuilder.create().addPart("media",
                new FileBody(file, ContentType.create("multipart/form-data", Consts.UTF_8), file.getName())).build();
        httpPost.setEntity(requestEntity);
        try {
            response = httpClient.execute(httpPost, new BasicHttpContext());

            if (response.getStatusLine().getStatusCode() != 200) {

                return null;
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");

                JSONObject result = JSON.parseObject(resultStr);
                //上传临时素材成功
                if (result.getString("errcode") == null) {
                    // 成功
                    return result;
                } else {
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("error code:" + errCode + ", error message:" + errMsg);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();                  //释放资源
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return null;
    }

    /**
     * 原生字符串发送put请求
     *
     * @param url
     * @param token
     * @param jsonStr
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String doPut(String url, String token, String jsonStr) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut httpPut = new HttpPut(url);
        //设置head信息
        setHead(httpPut, token);

        CloseableHttpResponse httpResponse = null;
        try {
            httpPut.setEntity(new StringEntity(jsonStr));
            httpResponse = httpClient.execute(httpPut);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 发送delete请求
     *
     * @param url
     * @param token
     * @param jsonStr
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String doDelete(String url, String token, String jsonStr) {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete httpDelete = new HttpDelete(url);
        //设置head信息
        setHead(httpDelete, token);

        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpDelete);
            HttpEntity entity = httpResponse.getEntity();
            String result = EntityUtils.toString(entity);
            return result;
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static void setHead(HttpRequestBase requestBase, String token) {
        HttpHost proxy = new HttpHost("127.0.0.1", 7890, "http");
        RequestConfig requestConfig = RequestConfig.custom()
                .setProxy(proxy)
                .setConnectTimeout(CONNECTTIMEOUT)
                .setConnectionRequestTimeout(CONNECTTIMEOUT)
                .setSocketTimeout(SOCKETTIMEOUT).build();
        requestBase.setConfig(requestConfig);
        requestBase.setHeader("Content-type", "application/json");
        requestBase.setHeader("DataEncoding", "UTF-8");
        if(StringUtils.isNotBlank(token)){
            requestBase.setHeader("token", token);
        }

    }

}
